from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
import json
import os
import zipfile
import tempfile
from datetime import datetime
import shutil

# 导入自定义模块
from models.survey_models import (
    SurveyData,
    FileData,
    ExportRequest,
    RockwoodSurveyData,
    RockwoodExportRequest,
    GPMSurveyData,
    GPMExportRequest,
    NRSSurveyData,
    NRSExportRequest,
    PSQISurveyData,
    PSQIExportRequest,
    HAMDSurveyData,
    HAMDExportRequest,
    OralSurveyData,
    OralExportRequest,
    OHIP14SurveyData,
    OHIP14ExportRequest,
    PersonalInfoSurveyData,
    PersonalInfoExportRequest,
    CognitiveSurveyData,
    CognitiveExportRequest,
    PersonalitySurveyData,
    PersonalityExportRequest,
    OutdoorActivitySurveyData,
    OutdoorActivityExportRequest,
    LeisureActivitySurveyData,
    LeisureActivityExportRequest,
    BatchExportRequest,
)
from services.frailty_service import FrailtyService
from utils.report_generator import ReportGenerator
from utils.text_parser import TextParser
from config import get_password

app = FastAPI(
    title="问卷调查API",
    version="1.0.0",
    # 使用国内 CDN 镜像
    swagger_ui_parameters={"syntaxHighlight.theme": "obsidian"},
)

# 自定义 Swagger UI 和 ReDoc 的 CDN 地址
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
)


@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    return get_swagger_ui_html(
        openapi_url=app.openapi_url,
        title=app.title + " - Swagger UI",
        swagger_js_url="https://cdn.bootcdn.net/ajax/libs/swagger-ui/4.15.5/swagger-ui-bundle.min.js",
        swagger_css_url="https://cdn.bootcdn.net/ajax/libs/swagger-ui/4.15.5/swagger-ui.min.css",
    )


@app.get("/redoc", include_in_schema=False)
async def redoc_html():
    return get_redoc_html(
        openapi_url=app.openapi_url,
        title=app.title + " - ReDoc",
        redoc_js_url="https://cdn.bootcdn.net/ajax/libs/redoc/2.0.0/bundles/redoc.standalone.js",
    )


# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://localhost:1008",  # Vue开发服务器配置端口
        "http://localhost:8080",  # Vue开发服务器默认端口
        "http://localhost:10080",
        "http://106.52.105.202:10080",
        "http://106.52.105.202:13000",
        "http://106.52.105.202:8081",
        "http://localhost:13000",
        "http://localhost:8081",
        "http://localhost:1024",
    ],  # Vue应用的地址
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 数据目录
DATA_DIR = "survey_data"
REPORT_DIR = "@data"

# 确保目录存在
os.makedirs(DATA_DIR, exist_ok=True)
os.makedirs(REPORT_DIR, exist_ok=True)

# 数据模型已移至 models/survey_models.py


@app.get("/")
async def root():
    return {"message": "问卷调查API服务正在运行"}


@app.post("/api/save-survey")
async def save_survey(survey_data: SurveyData):
    """保存问卷数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId
        patient_name = survey_data.patientName
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # 创建按surveyId分组的目录
        group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 生成文件名
        filename = f"{patient_name}_{timestamp}.json"
        filepath = os.path.join(group_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        print(f"问卷数据已保存: {filepath}")
        return {"success": True, "message": "问卷数据保存成功", "filepath": filepath}

    except Exception as e:
        print(f"保存问卷数据失败: {e}")
        raise HTTPException(status_code=500, detail="保存问卷数据失败")


@app.post("/api/save-file")
async def save_file(file_data: FileData):
    """保存评估报告文件到@data目录，并自动转换为JSON格式保存到survey_data目录"""
    try:
        survey_id = file_data.surveyId
        filename = file_data.filename
        content = file_data.content

        # 创建按surveyId分组的目录
        group_dir = os.path.join(REPORT_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 保存TXT文件
        filepath = os.path.join(group_dir, filename)
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(content)

        print(f"报告文件已保存: {filepath}")

        # 自动转换为JSON格式并保存到survey_data目录（PSQI、NRS、GPM、Rockwood除外，因为它们有专门的保存API）
        # if not filename.startswith('PSQI') and not filename.startswith('NRS') and not filename.startswith('GPM') and not filename.startswith('Rockwood') and not filename.startswith('HAMD'):
        #     try:
        #         json_data = TextParser.parse_txt_to_json(content)

        #         # 创建survey_data目录
        #         survey_group_dir = os.path.join(DATA_DIR, survey_id)
        #         os.makedirs(survey_group_dir, exist_ok=True)

        #         # 生成JSON文件名
        #         json_filename = filename.replace('.txt', '.json')
        #         json_filepath = os.path.join(survey_group_dir, json_filename)

        #         # 保存JSON文件
        #         with open(json_filepath, 'w', encoding='utf-8') as f:
        #             json.dump(json_data, f, ensure_ascii=False, indent=2)

        #         print(f"JSON数据已自动生成: {json_filepath}")

        #     except Exception as json_error:
        #         print(f"JSON转换失败: {json_error}")
        # 不影响TXT文件保存，继续执行
        # else:
        #     print(f"PSQI/NRS/GPM/Rockwood文件跳过自动JSON转换，使用专门的保存API")

        return {"success": True, "message": "文件保存成功", "filepath": filepath}

    except Exception as e:
        print(f"保存文件失败: {e}")
        raise HTTPException(status_code=500, detail="保存文件失败")


@app.post("/api/export-survey")
async def export_survey(export_request: ExportRequest):
    """导出问卷数据为压缩包"""
    try:
        survey_id = export_request.surveyId
        password = export_request.password
        survey_type = export_request.surveyType

        # 根据问卷类型使用不同的密码验证
        # 如果指定了surveyType，使用对应的密码；否则使用默认的survey密码
        if survey_type:
            # 将surveyType映射到密码类型
            password_type = survey_type.lower()
            # 验证密码
            if password != get_password(password_type):
                raise HTTPException(status_code=401, detail="密码错误")
        else:
            # 默认使用survey密码（向后兼容）
            if password != get_password("survey"):
                raise HTTPException(status_code=401, detail="密码错误")

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有JSON文件
        json_files = [f for f in os.listdir(group_dir) if f.endswith(".json")]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = ReportGenerator.generate_summary_report(
                surveys, survey_id
            )
            summary_file = os.path.join(temp_dir, f"汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件
            csv_content = ReportGenerator.generate_csv_report(surveys)
            csv_file = os.path.join(temp_dir, f"问卷数据_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # 复制个人报告文件（如果存在）
            report_group_dir = os.path.join(REPORT_DIR, survey_id)
            if os.path.exists(report_group_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for report_file in os.listdir(report_group_dir):
                    if report_file.endswith(".txt"):
                        src = os.path.join(report_group_dir, report_file)
                        dst = os.path.join(individual_dir, report_file)
                        shutil.copy2(src, dst)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"问卷数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到临时位置供下载
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        print(f"导出数据失败: {e}")
        raise HTTPException(status_code=500, detail="导出数据失败")


@app.post("/api/get-survey-result")
async def get_survey_result(survey_data: dict):
    """根据问卷数据计算衰弱评分并生成评估报告"""
    try:
        # 计算衰弱评分
        score = FrailtyService.calculate_frailty_score(survey_data)
        result = FrailtyService.get_frailty_result(score)

        # 生成个人评估报告
        report = ReportGenerator.generate_individual_report(survey_data, score, result)

        return {"success": True, "score": score, "result": result, "report": report}

    except Exception as e:
        print(f"生成评估报告失败: {e}")
        raise HTTPException(status_code=500, detail="生成评估报告失败")


@app.post("/api/save-rockwood-survey")
async def save_rockwood_survey(survey_data: RockwoodSurveyData):
    """保存Rockwood CFS问卷数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId
        patient_name = survey_data.patientName
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # 创建按surveyId分组的目录
        group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 生成文件名
        filename = f"rockwood_{patient_name}_{timestamp}.json"
        filepath = os.path.join(group_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        print(f"Rockwood CFS问卷数据已保存: {filepath}")
        return {
            "success": True,
            "message": "Rockwood CFS问卷数据保存成功",
            "filepath": filepath,
        }

    except Exception as e:
        print(f"保存Rockwood CFS问卷数据失败: {e}")
        raise HTTPException(status_code=500, detail="保存Rockwood CFS问卷数据失败")


@app.post("/api/export-rockwood-survey")
async def export_rockwood_survey(export_request: RockwoodExportRequest):
    """导出Rockwood CFS问卷数据为压缩包"""
    try:
        survey_id = export_request.surveyId
        password = export_request.password

        # 验证密码（这里使用简单的密码验证）
        if password != get_password("rockwood"):
            raise HTTPException(status_code=401, detail="密码错误")

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有Rockwood JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.startswith("rockwood_") and f.endswith(".json")
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有Rockwood CFS数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"Rockwood CFS评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(
                temp_dir, f"Rockwood_CFS_汇总报告_{survey_id}.txt"
            )
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件
            csv_content = "序号,姓名,年龄,性别,身高(cm),体重(kg),CFS评分,衰弱等级,功能状态,活动能力,联系电话,记录时间,备注\n"
            for i, survey in enumerate(surveys, 1):
                csv_content += f"{i},{survey.get('patientName', '')},{survey.get('age', '')},{survey.get('gender', '')},{survey.get('height', '')},{survey.get('weight', '')},{survey.get('cfsScore', '')},{survey.get('frailtyLevel', '')},{survey.get('functionalAssessment', '')},{survey.get('mobilityLevel', '')},{survey.get('phone', '')},{survey.get('recordTime', '')},{survey.get('remarks', '')}\n"

            csv_file = os.path.join(temp_dir, f"Rockwood_CFS_数据_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                txt_files = [
                    f
                    for f in os.listdir(report_dir)
                    if f.startswith("Rockwood临床衰弱量表评估结果")
                    and f.endswith(".txt")
                ]
                for txt_file in txt_files:
                    src = os.path.join(report_dir, txt_file)
                    dst = os.path.join(individual_dir, txt_file)
                    shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"Rockwood_CFS_数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到临时位置供下载
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"Rockwood CFS导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        print(f"导出Rockwood CFS数据失败: {e}")
        raise HTTPException(status_code=500, detail="导出Rockwood CFS数据失败")


@app.post("/api/save-gpm-survey")
async def save_gpm_survey(survey_data: GPMSurveyData):
    """保存GPM疼痛量表问卷数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId
        patient_name = survey_data.patientName
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # 创建按surveyId分组的目录
        group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 生成文件名
        filename = f"gpm_{patient_name}_{timestamp}.json"
        filepath = os.path.join(group_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        print(f"GPM疼痛量表问卷数据已保存: {filepath}")
        return {
            "success": True,
            "message": "GPM疼痛量表问卷数据保存成功",
            "filepath": filepath,
        }

    except Exception as e:
        print(f"保存GPM疼痛量表问卷数据失败: {e}")
        raise HTTPException(status_code=500, detail="保存GPM疼痛量表问卷数据失败")


@app.post("/api/export-gpm-survey")
async def export_gpm_survey(export_request: GPMExportRequest):
    """导出GPM疼痛量表问卷数据为压缩包"""
    try:
        survey_id = export_request.surveyId
        password = export_request.password

        # 验证密码（这里使用简单的密码验证）
        if password != get_password("gpm"):
            raise HTTPException(status_code=401, detail="密码错误")

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有GPM JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.startswith("gpm_") and f.endswith(".json")
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有GPM疼痛量表数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"GPM老年疼痛量表评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(
                temp_dir, f"GPM_疼痛量表_汇总报告_{survey_id}.txt"
            )
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件 - 列出所有选项而不是计算总分
            csv_headers = [
                "序号",
                "姓名",
                "年龄",
                "性别",
                "身高(cm)",
                "体重(kg)",
                # 维度一：疼痛强度和频率
                "静息疼痛",
                "活动疼痛",
                "疼痛频率",
                "夜间痛醒",
                "疼痛持续时间",
                # 维度二：日常生活活动能力
                "穿衣能力",
                "进食能力",
                "行走能力",
                "如厕能力",
                "洗漱能力",
                "睡眠质量",
                "家务活动",
                # 维度三：心理情绪状态
                "焦虑情绪",
                "抑郁情绪",
                "易怒倾向",
                "无助感",
                "注意力集中",
                "生活乐趣",
                # 维度四：社会功能
                "社交参与",
                "家庭角色",
                "工作能力",
                "亲密关系",
                # 维度五：疼痛管理
                "疼痛缓解效果",
                "就医主动性",
                # 其他信息
                "疼痛描述",
                "优先改善需求",
                "联系电话",
                "记录时间",
                "备注",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                csv_row = [
                    str(i),
                    survey.get("patientName") or "",
                    str(survey.get("age") or ""),
                    survey.get("gender") or "",
                    str(survey.get("height") or ""),
                    str(survey.get("weight") or ""),
                    # 维度一：疼痛强度和频率
                    str(survey.get("restPain") or ""),
                    str(survey.get("activityPain") or ""),
                    str(survey.get("painFrequency") or ""),
                    str(survey.get("nightWakeups") or ""),
                    str(survey.get("painDuration") or ""),
                    # 维度二：日常生活活动能力
                    str(survey.get("dressingAbility") or ""),
                    str(survey.get("eatingAbility") or ""),
                    str(survey.get("walkingAbility") or ""),
                    str(survey.get("toiletingAbility") or ""),
                    str(survey.get("hygieneAbility") or ""),
                    str(survey.get("sleepQuality") or ""),
                    str(survey.get("houseworkAbility") or ""),
                    # 维度三：心理情绪状态
                    str(survey.get("anxiety") or ""),
                    str(survey.get("depression") or ""),
                    str(survey.get("irritability") or ""),
                    str(survey.get("helplessness") or ""),
                    str(survey.get("concentration") or ""),
                    str(survey.get("lifeEnjoyment") or ""),
                    # 维度四：社会功能
                    str(survey.get("socialParticipation") or ""),
                    str(survey.get("familyRole") or ""),
                    str(survey.get("workAbility") or ""),
                    str(survey.get("intimateRelationship") or ""),
                    # 维度五：疼痛管理
                    str(survey.get("painReliefEffect") or ""),
                    str(survey.get("medicalSeeking") or ""),
                    # 其他信息
                    (survey.get("painDescription") or "").replace(",", "；").replace("\n", " ") if survey.get("painDescription") else "",
                    (survey.get("priorityImprovement") or "").replace(",", "；").replace("\n", " ") if survey.get("priorityImprovement") else "",
                    survey.get("phone") or "",
                    survey.get("recordTime") or "",
                    (survey.get("remarks") or "").replace(",", "；").replace("\n", " ") if survey.get("remarks") else "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"GPM_疼痛量表_数据_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "GPM" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"GPM_疼痛量表_数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到临时位置供下载
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"GPM疼痛量表导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        print(f"导出GPM疼痛量表数据失败: {e}")
        raise HTTPException(status_code=500, detail="导出GPM疼痛量表数据失败")


# 报告生成函数已移至 utils/report_generator.py

# CSV报告生成和评分计算函数已移至相应模块

# 文本解析函数已移至 utils/text_parser.py


@app.post("/api/save-nrs-survey")
async def save_nrs_survey(survey_data: NRSSurveyData):
    """保存NRS疼痛评估量表问卷数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId
        patient_name = survey_data.patientName
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # 创建按surveyId分组的目录
        group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 生成文件名
        filename = f"nrs_{patient_name}_{timestamp}.json"
        filepath = os.path.join(group_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        print(f"NRS疼痛评估量表问卷数据已保存: {filepath}")
        return {
            "success": True,
            "message": "NRS疼痛评估量表问卷数据保存成功",
            "filepath": filepath,
        }

    except Exception as e:
        print(f"保存NRS疼痛评估量表问卷数据失败: {e}")
        raise HTTPException(status_code=500, detail="保存NRS疼痛评估量表问卷数据失败")


@app.post("/api/export-nrs-survey")
async def export_nrs_survey(export_request: NRSExportRequest):
    """导出NRS疼痛评估量表问卷数据为压缩包"""
    try:
        survey_id = export_request.surveyId
        password = export_request.password

        # 验证密码（这里使用简单的密码验证）
        if password != get_password("nrs"):
            raise HTTPException(status_code=401, detail="密码错误")

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有NRS JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.startswith("nrs_") and f.endswith(".json")
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有NRS疼痛评估量表数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"NRS疼痛评估量表数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(
                temp_dir, f"NRS_疼痛评估量表_汇总报告_{survey_id}.txt"
            )
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件 - 列出所有评估项目的原始分值
            csv_headers = [
                "序号",
                "姓名",
                "年龄",
                "性别",
                "诊断",
                "联系电话",
                "记录时间",
                # NRS疼痛评估项目 (0-10分)
                "当前疼痛程度",
                "24h最严重疼痛",
                "24h最轻微疼痛",
                "24h平均疼痛",
                "静息时疼痛",
                "活动时疼痛",
                "功能影响程度",
                # 疼痛特征
                "疼痛部位",
                "疼痛性质",
                "疼痛持续时间",
                "诱发因素",
                "缓解因素",
                # 评估结果
                "最高疼痛评分",
                "疼痛等级",
                "疼痛等级范围",
                "备注",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                # 处理疼痛性质列表
                pain_character = survey.get("painCharacter", [])
                if isinstance(pain_character, list):
                    pain_character_str = "；".join(pain_character)
                else:
                    pain_character_str = str(pain_character)

                csv_row = [
                    str(i),
                    survey.get("patientName") or "",
                    str(survey.get("age") or ""),
                    survey.get("gender") or "",
                    survey.get("diagnosis") or "",
                    survey.get("phone") or "",
                    survey.get("recordTime") or "",
                    # NRS疼痛评估项目
                    str(survey.get("currentPain") or ""),
                    str(survey.get("worstPain24h") or ""),
                    str(survey.get("leastPain24h") or ""),
                    str(survey.get("averagePain24h") or ""),
                    str(survey.get("restPain") or ""),
                    str(survey.get("activityPain") or ""),
                    str(survey.get("functionalImpact") or ""),
                    # 疼痛特征
                    (survey.get("painLocation") or "").replace(",", "；").replace("\n", " ") if survey.get("painLocation") else "",
                    pain_character_str.replace(",", "；").replace("\n", " ") if pain_character_str else "",
                    (survey.get("painDuration") or "").replace(",", "；").replace("\n", " ") if survey.get("painDuration") else "",
                    (survey.get("painTriggers") or "").replace(",", "；").replace("\n", " ") if survey.get("painTriggers") else "",
                    (survey.get("painRelief") or "").replace(",", "；").replace("\n", " ") if survey.get("painRelief") else "",
                    # 评估结果
                    str(survey.get("maxPainScore") or ""),
                    survey.get("painLevel") or "",
                    survey.get("painLevelRange") or "",
                    (survey.get("remarks") or "").replace(",", "；").replace("\n", " ") if survey.get("remarks") else "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"NRS_疼痛评估量表_数据_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "NRS" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"NRS_疼痛评估量表_数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到临时位置供下载
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"NRS疼痛评估量表导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        print(f"导出NRS疼痛评估量表数据失败: {e}")
        raise HTTPException(status_code=500, detail="导出NRS疼痛评估量表数据失败")


@app.post("/api/save-psqi-survey")
async def save_psqi_survey(survey_data: PSQISurveyData):
    """保存PSQI睡眠质量评估数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId

        # 创建按surveyId分组的目录（与其他问卷保持一致）
        survey_group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(survey_group_dir, exist_ok=True)

        # 生成标准格式的文件名
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"PSQI睡眠质量评估结果_{survey_id}_{patient_name}_{timestamp}.json"
        data_file = os.path.join(survey_group_dir, filename)

        # 保存原始数据
        with open(data_file, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {
            "success": True,
            "message": "PSQI睡眠质量评估数据保存成功",
            "surveyId": survey_id,
            "filename": filename,
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-psqi-survey")
async def export_psqi_survey(export_request: PSQIExportRequest):
    """导出PSQI睡眠质量评估结果"""
    try:
        # 验证密码
        if export_request.password != get_password("psqi"):
            raise HTTPException(status_code=401, detail="密码错误")

        # 获取PSQI数据目录 - 从新的目录结构读取
        survey_id = export_request.surveyId
        psqi_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(psqi_dir):
            raise HTTPException(status_code=404, detail="未找到PSQI评估数据")

        # 创建临时目录用于打包
        with tempfile.TemporaryDirectory() as temp_dir:
            # 复制所有PSQI数据文件
            data_files = [
                f
                for f in os.listdir(psqi_dir)
                if f.startswith("PSQI睡眠质量评估结果") and f.endswith(".json")
            ]

            if not data_files:
                raise HTTPException(status_code=404, detail="未找到PSQI评估数据文件")

            surveys = []
            for data_file in data_files:
                src_file = os.path.join(psqi_dir, data_file)
                with open(src_file, "r", encoding="utf-8") as f:
                    data = json.load(f)
                    surveys.append(data)

            # 生成汇总报告
            summary_content = f"PSQI睡眠质量评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n\n"
            for i, survey in enumerate(surveys, 1):
                summary_content += f"第{i}人：{survey.get('patientName', '')}，年龄：{survey.get('age', '')}，性别：{survey.get('gender', '')}，PSQI总分：{survey.get('totalScore', '')}，诊断：{survey.get('diagnosis', '')}\n"

            summary_file = os.path.join(
                temp_dir, f"PSQI睡眠质量评估_汇总报告_{survey_id}.txt"
            )
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件（问卷调查）
            csv_headers = [
                "序号",
                "患者姓名",
                "年龄",
                "性别",
                "评估日期",
                "PSQI总分",
                "睡眠质量等级",
                "记录时间",
            ]
            csv_content = ",".join(csv_headers) + "\n"
            for i, survey in enumerate(surveys, 1):
                csv_row = [
                    str(i),
                    survey.get("patientName") or "",
                    str(survey.get("age") or ""),
                    survey.get("gender") or "",
                    survey.get("assessmentDate") or "",
                    str(survey.get("totalScore") or ""),
                    survey.get("diagnosis") or "",
                    survey.get("createdAt") or "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(
                temp_dir, f"PSQI睡眠质量评估_问卷调查_{survey_id}.csv"
            )
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for data_file in data_files:
                src_file = os.path.join(psqi_dir, data_file)
                dst_file = os.path.join(json_data_dir, data_file)
                shutil.copy2(src_file, dst_file)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "PSQI" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"PSQI睡眠质量评估结果_{survey_id}_{timestamp}.zip"
            zip_path = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_path, final_zip_path)

            print(f"PSQI导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/save-hamd-survey")
async def save_hamd_survey(survey_data: HAMDSurveyData):
    """保存HAMD问卷数据到JSON文件"""
    try:
        survey_id = survey_data.surveyId
        patient_name = survey_data.patientName
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")

        # 创建按surveyId分组的目录
        group_dir = os.path.join(DATA_DIR, survey_id)
        os.makedirs(group_dir, exist_ok=True)

        # 生成文件名
        filename = f"HAMD抑郁评估结果_{survey_id}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(group_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        print(f"HAMD问卷数据已保存: {filepath}")
        return {
            "success": True,
            "message": "HAMD问卷数据保存成功",
            "filepath": filepath,
        }

    except Exception as e:
        print(f"保存HAMD问卷数据失败: {e}")
        raise HTTPException(status_code=500, detail="保存HAMD问卷数据失败")


@app.post("/api/export-hamd-survey")
async def export_hamd_survey(export_request: HAMDExportRequest):
    """导出HAMD问卷数据为压缩包"""
    try:
        survey_id = export_request.surveyId
        password = export_request.password
        export_options = export_request.exportOptions

        # 验证密码
        if password != get_password("hamd"):
            raise HTTPException(status_code=401, detail="密码错误")

        # 检查目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(status_code=404, detail="未找到该问答编号的数据")

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 读取所有HAMD JSON文件
            json_files = [
                f for f in os.listdir(group_dir) if f.endswith(".json") and "HAMD" in f
            ]

            if not json_files:
                raise HTTPException(status_code=404, detail="没有找到HAMD问卷数据")

            surveys = []
            for json_file in json_files:
                filepath = os.path.join(group_dir, json_file)
                with open(filepath, "r", encoding="utf-8") as f:
                    survey_data = json.load(f)
                    surveys.append(survey_data)

            # 生成汇总报告
            summary_content = f"HAMD抑郁评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(
                temp_dir, f"HAMD抑郁评估_汇总报告_{survey_id}.txt"
            )
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件（问卷调查）
            csv_content = None
            if export_options.get("includeStatistics", True):
                try:
                    csv_content = ReportGenerator.generate_hamd_csv_report(group_dir)
                except Exception as e:
                    print(f"生成HAMD CSV报告失败: {e}")

            csv_file = None
            if csv_content:
                csv_file = os.path.join(
                    temp_dir, f"HAMD抑郁评估_问卷调查_{survey_id}.csv"
                )
                with open(csv_file, "w", encoding="utf-8-sig") as f:
                    f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            if export_options.get("includeRawData", True):
                for json_file in json_files:
                    src = os.path.join(group_dir, json_file)
                    dst = os.path.join(json_data_dir, json_file)
                    shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "HAMD" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"HAMD问卷数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                if csv_file and os.path.exists(csv_file):
                    zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"HAMD导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


# ==================== 口腔检查表相关API ====================


@app.post("/api/save-oral-survey")
async def save_oral_survey(survey_data: OralSurveyData):
    """保存口腔检查表数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"口腔检查结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "口腔检查数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-oral-survey")
async def export_oral_survey(request: OralExportRequest):
    """导出口腔检查表数据"""
    try:
        # 验证密码
        if request.password != get_password("oral"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 创建临时目录
        temp_dir = tempfile.mkdtemp()
        zip_filename = (
            f"口腔检查数据_{survey_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
        )
        zip_path = os.path.join(temp_dir, zip_filename)

        # 读取所有JSON数据文件
        survey_dir = os.path.join(DATA_DIR, survey_id)
        json_files = []
        surveys = []
        if os.path.exists(survey_dir):
            for filename in os.listdir(survey_dir):
                if filename.endswith(".json") and "口腔检查" in filename:
                    json_files.append(filename)
                    file_path = os.path.join(survey_dir, filename)
                    with open(file_path, "r", encoding="utf-8") as f:
                        surveys.append(json.load(f))

        if not surveys:
            raise HTTPException(status_code=404, detail="没有找到口腔检查数据")

        # 生成汇总报告
        summary_content = f"口腔检查数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总检查人数：{len(surveys)}人\n"
        summary_file = os.path.join(temp_dir, f"口腔检查_汇总报告_{survey_id}.txt")
        with open(summary_file, "w", encoding="utf-8") as f:
            f.write(summary_content)

        # 生成CSV文件 - 列出所有检查项目的详细信息
        csv_headers = [
            "序号",
            "姓名",
            "年龄",
            "性别",
            "病历号/身份证号",
            "籍贯",
            "联系电话",
            "检查日期",
            "检查医生",
            "检查医生职务",
            "所属机构",
            # 牙齿状况
            "是否有龋齿",
            "龋齿详细情况",
            "龋坏程度",
            "是否有牙齿缺损",
            "缺损原因",
            "缺损详细情况",
            "是否有牙齿缺失",
            "缺失牙位",
            "缺失时间",
            # 牙周情况
            "牙龈颜色",
            "牙龈质地",
            "牙龈出血情况",
            "牙龈异常描述",
            "牙周袋深度正常",
            "异常牙周袋深度记录",
            "最大牙周袋深度(mm)",
            "牙槽骨吸收程度",
            "吸收部位",
            # 口腔黏膜
            "口腔黏膜正常",
            "黏膜病变类型",
            "病变详细描述",
            # 颌面外科
            "面部对称性正常",
            "不对称情况描述",
            "关节弹响",
            "关节疼痛",
            "最大开口度(mm)",
            "其他异常表现",
            # 评估结果
            "总体健康状况",
            "风险等级",
            "检查总结",
            "备注",
            "创建时间",
        ]
        csv_content = ",".join(csv_headers) + "\n"

        for i, survey in enumerate(surveys, 1):
            # 处理性别显示
            gender_str = survey.get("gender", "")
            if gender_str == "male":
                gender_str = "男性"
            elif gender_str == "female":
                gender_str = "女性"

            # 处理布尔值显示
            def bool_to_str(val):
                if val is True:
                    return "是"
                elif val is False:
                    return "否"
                else:
                    return ""

            # 安全地处理字符串替换（处理None值）
            def safe_replace(val, default="", replace_comma=True):
                if val is None:
                    return default
                val_str = str(val)
                val_str = val_str.replace("\n", " ")
                if replace_comma:
                    val_str = val_str.replace(",", "；")
                return val_str

            csv_row = [
                str(i),
                safe_replace(survey.get("patientName")),
                str(survey.get("age") or ""),
                gender_str,
                safe_replace(survey.get("patientId")),
                safe_replace(survey.get("birthplace")),
                safe_replace(survey.get("phone")),
                safe_replace(survey.get("examDate")),
                safe_replace(survey.get("examinerName")),
                safe_replace(survey.get("examinerPosition")),
                safe_replace(survey.get("examinerInstitution")),
                # 牙齿状况
                bool_to_str(survey.get("cariesPresent")),
                safe_replace(survey.get("cariesDetails")),
                safe_replace(survey.get("cariesSeverity")),  # 可能包含逗号分隔的值
                bool_to_str(survey.get("defectPresent")),
                safe_replace(survey.get("defectCause")),  # 可能包含逗号分隔的值
                safe_replace(survey.get("defectDetails")),
                bool_to_str(survey.get("missingPresent")),
                safe_replace(survey.get("missingPositions")),
                safe_replace(survey.get("missingDuration")),
                # 牙周情况
                safe_replace(survey.get("gingivalColor")),
                safe_replace(survey.get("gingivalTexture")),
                safe_replace(survey.get("gingivalBleeding")),
                safe_replace(survey.get("gingivalAbnormalDesc")),
                bool_to_str(survey.get("pocketDepthNormal")),
                safe_replace(survey.get("pocketDepthDetails")),
                str(survey.get("pocketDepthMax") or ""),
                safe_replace(survey.get("boneResorption")),
                safe_replace(survey.get("boneResorptionSites")),
                # 口腔黏膜
                bool_to_str(survey.get("mucosaNormal")),
                safe_replace(survey.get("mucosaLesionType")),  # 可能包含逗号分隔的值
                safe_replace(survey.get("mucosaLesionDetails")),
                # 颌面外科
                bool_to_str(survey.get("facialSymmetryNormal")),
                safe_replace(survey.get("asymmetryDescription")),
                safe_replace(survey.get("tmjClicking")),
                safe_replace(survey.get("tmjPain")),
                str(survey.get("mouthOpening") or ""),
                safe_replace(survey.get("tmjOtherSymptoms")),
                # 评估结果
                safe_replace(survey.get("overallStatus")),
                safe_replace(survey.get("riskLevel")),
                safe_replace(survey.get("summary")),
                safe_replace(survey.get("remarks")),
                safe_replace(survey.get("createdAt")),
            ]
            csv_content += ",".join(csv_row) + "\n"

        csv_file = os.path.join(temp_dir, f"口腔检查数据_{survey_id}.csv")
        with open(csv_file, "w", encoding="utf-8-sig") as f:
            f.write(csv_content)

        # 复制JSON数据文件
        json_data_dir = os.path.join(temp_dir, "JSON数据")
        os.makedirs(json_data_dir, exist_ok=True)
        for json_file in json_files:
            src = os.path.join(survey_dir, json_file)
            dst = os.path.join(json_data_dir, json_file)
            shutil.copy2(src, dst)

        # 复制个人评估报告文件（如果存在）
        report_dir = os.path.join(REPORT_DIR, survey_id)
        individual_dir = None
        if os.path.exists(report_dir):
            individual_dir = os.path.join(temp_dir, "个人评估报告")
            os.makedirs(individual_dir, exist_ok=True)
            for filename in os.listdir(report_dir):
                if "口腔检查" in filename and filename.endswith(".txt"):
                    src = os.path.join(report_dir, filename)
                    dst = os.path.join(individual_dir, filename)
                    shutil.copy2(src, dst)

        # 创建压缩包
        with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
            # 1. 添加JSON数据文件
            if os.path.exists(json_data_dir):
                for root, dirs, files in os.walk(json_data_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        arc_name = os.path.relpath(file_path, temp_dir)
                        zipf.write(file_path, arc_name)
            # 2. 添加个人评估报告
            if individual_dir and os.path.exists(individual_dir):
                for root, dirs, files in os.walk(individual_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        arc_name = os.path.relpath(file_path, temp_dir)
                        zipf.write(file_path, arc_name)
            # 3. 添加汇总报告
            zipf.write(summary_file, os.path.basename(summary_file))
            # 4. 添加问卷调查（CSV）
            zipf.write(csv_file, os.path.basename(csv_file))

        # 将ZIP文件移动到temp目录供下载
        final_zip_path = os.path.join("temp", zip_filename)
        os.makedirs("temp", exist_ok=True)
        shutil.move(zip_path, final_zip_path)

        print(f"口腔检查导出文件已生成: {final_zip_path}")
        return FileResponse(
            final_zip_path, media_type="application/zip", filename=zip_filename
        )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/save-ohip14-survey")
async def save_ohip14_survey(survey_data: OHIP14SurveyData):
    """保存OHIP-14问卷数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"OHIP-14评估结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "OHIP-14数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-ohip14-survey")
async def export_ohip14_survey(request: OHIP14ExportRequest):
    """导出OHIP-14问卷数据"""
    try:
        # 验证密码
        if request.password != get_password("ohip14"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 创建临时目录
        temp_dir = tempfile.mkdtemp()
        zip_filename = (
            f"OHIP-14数据_{survey_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
        )
        zip_path = os.path.join(temp_dir, zip_filename)

        # 读取所有JSON数据文件（⚠️ 使用 DATA_DIR，不要使用未定义的变量）
        survey_dir = os.path.join(DATA_DIR, survey_id)
        json_files = []
        surveys = []
        if os.path.exists(survey_dir):
            for filename in os.listdir(survey_dir):
                if filename.endswith(".json") and "OHIP-14" in filename:
                    json_files.append(filename)
                    file_path = os.path.join(survey_dir, filename)
                    with open(file_path, "r", encoding="utf-8") as f:
                        surveys.append(json.load(f))

        if not surveys:
            raise HTTPException(status_code=404, detail="没有找到OHIP-14数据")

        # 生成汇总报告
        summary_content = f"OHIP-14评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
        summary_file = os.path.join(temp_dir, f"OHIP-14评估_汇总报告_{survey_id}.txt")
        with open(summary_file, "w", encoding="utf-8") as f:
            f.write(summary_content)

        # 生成CSV文件 - 列出所有评估项目的原始分值
        csv_headers = [
            "序号",
            "姓名",
            "年龄",
            "性别",
            "联系电话",
            "记录时间",
            "记录人姓名",
            "记录人职务",
            "所属机构",
            # OHIP-14的14个问题
            "Q01_影响发音",
            "Q02_味觉变差",
            "Q03_明显疼痛",
            "Q04_吃不舒服",
            "Q05_不自在",
            "Q06_紧张不安",
            "Q07_饮食不满意",
            "Q08_中途停止进餐",
            "Q09_难以休息",
            "Q10_感到尴尬",
            "Q11_容易发脾气",
            "Q12_难以完成工作",
            "Q13_生活不满意",
            "Q14_什么事都干不了",
            # 评估结果
            "总分",
            "最高分",
            "诊断结果",
            "备注",
        ]
        csv_content = ",".join(csv_headers) + "\n"

        for i, survey in enumerate(surveys, 1):
            # 处理性别显示
            gender_str = survey.get("gender", "")
            if gender_str == "male":
                gender_str = "男性"
            elif gender_str == "female":
                gender_str = "女性"

            csv_row = [
                str(i),
                survey.get("patientName") or "",
                str(survey.get("age") or ""),
                gender_str,
                survey.get("phone") or "",
                survey.get("recordTime") or "",
                survey.get("recorderName") or "",
                survey.get("recorderPosition") or "",
                survey.get("recorderInstitution") or "",
                # OHIP-14的14个问题
                str(survey.get("Q01") or ""),
                str(survey.get("Q02") or ""),
                str(survey.get("Q03") or ""),
                str(survey.get("Q04") or ""),
                str(survey.get("Q05") or ""),
                str(survey.get("Q06") or ""),
                str(survey.get("Q07") or ""),
                str(survey.get("Q08") or ""),
                str(survey.get("Q09") or ""),
                str(survey.get("Q10") or ""),
                str(survey.get("Q11") or ""),
                str(survey.get("Q12") or ""),
                str(survey.get("Q13") or ""),
                str(survey.get("Q14") or ""),
                # 评估结果
                str(survey.get("totalScore") or ""),
                str(survey.get("maxScore") or ""),
                (survey.get("diagnosis") or "").replace(",", "；") if survey.get("diagnosis") else "",
                (survey.get("remarks") or "").replace(",", "；").replace("\n", " ") if survey.get("remarks") else "",
            ]
            csv_content += ",".join(csv_row) + "\n"

        csv_file = os.path.join(temp_dir, f"OHIP-14评估数据_{survey_id}.csv")
        with open(csv_file, "w", encoding="utf-8") as f:
            f.write(csv_content)

        # 复制JSON数据文件
        json_data_dir = os.path.join(temp_dir, "JSON数据")
        os.makedirs(json_data_dir, exist_ok=True)
        for json_file in json_files:
            src = os.path.join(survey_dir, json_file)
            dst = os.path.join(json_data_dir, json_file)
            shutil.copy2(src, dst)

        # 复制个人评估报告文件（如果存在）
        report_dir = os.path.join(REPORT_DIR, survey_id)
        individual_dir = None
        if os.path.exists(report_dir):
            individual_dir = os.path.join(temp_dir, "个人评估报告")
            os.makedirs(individual_dir, exist_ok=True)
            for filename in os.listdir(report_dir):
                if "OHIP-14" in filename and filename.endswith(".txt"):
                    src = os.path.join(report_dir, filename)
                    dst = os.path.join(individual_dir, filename)
                    shutil.copy2(src, dst)

        # 创建压缩包
        with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
            # 1. 添加JSON数据文件
            if os.path.exists(json_data_dir):
                for root, dirs, files in os.walk(json_data_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        arc_name = os.path.relpath(file_path, temp_dir)
                        zipf.write(file_path, arc_name)
            # 2. 添加个人评估报告
            if individual_dir and os.path.exists(individual_dir):
                for root, dirs, files in os.walk(individual_dir):
                    for file in files:
                        file_path = os.path.join(root, file)
                        arc_name = os.path.relpath(file_path, temp_dir)
                        zipf.write(file_path, arc_name)
            # 3. 添加汇总报告
            zipf.write(summary_file, os.path.basename(summary_file))
            # 4. 添加问卷调查（CSV）
            zipf.write(csv_file, os.path.basename(csv_file))

        # 将ZIP文件移动到temp目录供下载
        final_zip_path = os.path.join("temp", zip_filename)
        os.makedirs("temp", exist_ok=True)
        shutil.move(zip_path, final_zip_path)

        print(f"OHIP-14导出文件已生成: {final_zip_path}")
        return FileResponse(
            final_zip_path, media_type="application/zip", filename=zip_filename
        )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/save-personal-info-survey")
async def save_personal_info_survey(survey_data: PersonalInfoSurveyData):
    """保存个人信息登记表数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"个人信息登记结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "个人信息登记数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/save-cognitive-survey")
async def save_cognitive_survey(survey_data: CognitiveSurveyData):
    """保存认知能力评估数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"认知能力评估结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "认知能力评估数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-cognitive-survey")
async def export_cognitive_survey(request: CognitiveExportRequest):
    """导出认知能力评估数据"""
    try:
        # 验证密码
        if request.password != get_password("cognitive"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有认知能力评估 JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.endswith(".json") and "认知能力" in f
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有认知能力评估数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"认知能力评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(temp_dir, f"认知能力评估_汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件 - 根据新的字段结构
            csv_headers = [
                "序号",
                "问答编号",
                "姓名",
                "编号",
                "年龄",
                "性别",
                "教育程度",
                "联系电话",
                "评估日期",
                "测量地点",
                "测量人员",
                "记录时间",
                "记录人姓名",
                "记录人职务",
                "所属机构",
                "记录人联系方式",
                "备注",
                # 1. 注意
                "鼻子(记住)",
                "丝绸(记住)",
                "寺庙(记住)",
                "菊花(记住)",
                "红色(记住)",
                "注意得分",
                # 2. 执行功能/言语
                "动物名字个数",
                "动物名字列表",
                # 3. 定向
                "年",
                "月",
                "日",
                "星期几",
                "地点",
                "城市",
                "定向得分",
                # 4. 记忆
                "无提示回忆",
                "无提示回忆得分",
                "分类提示回忆",
                "分类提示回忆得分",
                "多选提示回忆",
                "多选提示回忆得分",
                # 5. 计算能力
                "计算题目1",
                "答案1",
                "计算题目2",
                "答案2",
                "计算题目3",
                "答案3",
                "计算能力得分",
                # 各维度得分汇总
                "注意总分",
                "注意最高分",
                "注意百分比",
                "注意水平",
                "执行功能总分",
                "执行功能最高分",
                "执行功能百分比",
                "执行功能水平",
                "定向总分",
                "定向最高分",
                "定向百分比",
                "定向水平",
                "记忆总分",
                "记忆最高分",
                "记忆百分比",
                "记忆水平",
                "计算能力总分",
                "计算能力最高分",
                "计算能力百分比",
                "计算能力水平",
                # 总体评估结果
                "总分",
                "最高分",
                "百分比",
                "认知功能水平",
                "认知功能水平名称",
                "诊断结果",
                "建议措施",
                "创建时间",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                # 处理性别（安全处理None值）
                gender_str = survey.get("gender") or ""
                if gender_str == "male":
                    gender_str = "男性"
                elif gender_str == "female":
                    gender_str = "女性"
                else:
                    gender_str = gender_str or ""

                # 处理教育程度（安全处理None值）
                education_str = survey.get("education") or ""
                education_map = {
                    "illiterate": "文盲",
                    "primary": "小学",
                    "middle": "初中",
                    "high": "高中/中专",
                    "college": "大专",
                    "university": "本科",
                    "graduate": "研究生及以上"
                }
                education_str = education_map.get(education_str, education_str) if education_str else ""

                # 获取各维度详细数据
                dimensions = survey.get("dimensions", {})
                attention_dim = dimensions.get("attention", {}) if dimensions else {}
                executive_dim = dimensions.get("executive", {}) if dimensions else {}
                orientation_dim = dimensions.get("orientation", {}) if dimensions else {}
                memory_dim = dimensions.get("memory", {}) if dimensions else {}
                calculation_dim = dimensions.get("calculation", {}) if dimensions else {}

                # 安全处理可能为None的字段
                diagnosis_str = survey.get("diagnosis") or ""
                diagnosis_str = diagnosis_str.replace(",", "；").replace("\n", " ") if diagnosis_str else ""
                
                remarks_str = survey.get("remarks") or ""
                remarks_str = remarks_str.replace(",", "；").replace("\n", " ") if remarks_str else ""
                
                # 处理建议措施（数组转字符串）
                recommendations = survey.get("recommendations", [])
                recommendations_str = ""
                if recommendations and isinstance(recommendations, list):
                    recommendations_str = "；".join([str(r).replace(",", "，").replace("\n", " ") for r in recommendations])
                elif recommendations:
                    recommendations_str = str(recommendations).replace(",", "，").replace("\n", " ")
                
                # 处理注意词语（布尔值转是/否）
                attention_word1 = "是" if survey.get("attentionWord1") else "否"
                attention_word2 = "是" if survey.get("attentionWord2") else "否"
                attention_word3 = "是" if survey.get("attentionWord3") else "否"
                attention_word4 = "是" if survey.get("attentionWord4") else "否"
                attention_word5 = "是" if survey.get("attentionWord5") else "否"
                
                csv_row = [
                    str(i),
                    survey.get("surveyId") or "",
                    survey.get("patientName") or "",
                    survey.get("patientId") or "",
                    str(survey.get("age") or ""),
                    gender_str,
                    education_str,
                    survey.get("phone") or "",
                    survey.get("recordTime") or "",
                    survey.get("measurementLocation") or "",
                    survey.get("measurementPerson") or "",
                    survey.get("recordTime") or "",
                    survey.get("recorderName") or "",
                    survey.get("recorderPosition") or "",
                    survey.get("recorderInstitution") or "",
                    survey.get("recorderContact") or "",
                    remarks_str,
                    # 1. 注意
                    attention_word1,
                    attention_word2,
                    attention_word3,
                    attention_word4,
                    attention_word5,
                    str(survey.get("attentionScore") or ""),
                    # 2. 执行功能/言语
                    str(survey.get("animalNamesCount") or ""),
                    (survey.get("animalNamesList") or "").replace(",", "；").replace("\n", " ") if survey.get("animalNamesList") else "",
                    # 3. 定向
                    str(survey.get("orientationYear") or ""),
                    str(survey.get("orientationMonth") or ""),
                    str(survey.get("orientationDay") or ""),
                    survey.get("orientationWeekday") or "",
                    survey.get("orientationLocation") or "",
                    survey.get("orientationCity") or "",
                    str(survey.get("orientationScore") or ""),
                    # 4. 记忆
                    (survey.get("memoryNoHint") or "").replace(",", "；").replace("\n", " ") if survey.get("memoryNoHint") else "",
                    str(survey.get("memoryNoHintScore") or ""),
                    (survey.get("memoryCategoryHint") or "").replace(",", "；").replace("\n", " ") if survey.get("memoryCategoryHint") else "",
                    str(survey.get("memoryCategoryHintScore") or ""),
                    (survey.get("memoryMultipleChoice") or "").replace(",", "；").replace("\n", " ") if survey.get("memoryMultipleChoice") else "",
                    str(survey.get("memoryMultipleChoiceScore") or ""),
                    # 5. 计算能力
                    survey.get("calculationQuestion1") or "",
                    survey.get("calculationAnswer1") or "",
                    survey.get("calculationQuestion2") or "",
                    survey.get("calculationAnswer2") or "",
                    survey.get("calculationQuestion3") or "",
                    survey.get("calculationAnswer3") or "",
                    str(survey.get("calculationScore") or ""),
                    # 各维度得分汇总
                    str(attention_dim.get("total") or ""),
                    str(attention_dim.get("max") or ""),
                    attention_dim.get("percentage") or "",
                    attention_dim.get("level") or "",
                    str(executive_dim.get("total") or ""),
                    str(executive_dim.get("max") or ""),
                    executive_dim.get("percentage") or "",
                    executive_dim.get("level") or "",
                    str(orientation_dim.get("total") or ""),
                    str(orientation_dim.get("max") or ""),
                    orientation_dim.get("percentage") or "",
                    orientation_dim.get("level") or "",
                    str(memory_dim.get("total") or ""),
                    str(memory_dim.get("max") or ""),
                    memory_dim.get("percentage") or "",
                    memory_dim.get("level") or "",
                    str(calculation_dim.get("total") or ""),
                    str(calculation_dim.get("max") or ""),
                    calculation_dim.get("percentage") or "",
                    calculation_dim.get("level") or "",
                    # 总体评估结果
                    str(survey.get("totalScore") or ""),
                    str(survey.get("maxScore") or ""),
                    str(survey.get("percentage") or ""),
                    survey.get("cognitiveLevel") or "",
                    survey.get("cognitiveLevelName") or "",
                    diagnosis_str,
                    recommendations_str,
                    survey.get("createdAt") or "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"认知能力评估_问卷调查_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "认知能力" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"认知能力评估数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"认知能力评估导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/export-personal-info-survey")
async def export_personal_info_survey(request: PersonalInfoExportRequest):
    """导出个人信息登记表数据"""
    try:
        # 验证密码
        if request.password != get_password("personalinfo"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有个人信息 JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.endswith(".json") and "个人信息" in f
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有个人信息登记数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"个人信息登记数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总登记人数：{len(surveys)}人\n"
            summary_file = os.path.join(temp_dir, f"个人信息登记_汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件（个人信息登记）
            csv_headers = [
                "序号",
                "姓名",
                "身份证号",
                "年龄",
                "性别",
                "出生日期",
                "联系电话",
                "电子邮箱",
                "居住地址",
                "婚姻状况",
                "教育程度",
                "职业",
                "是否退休",
                "身高(cm)",
                "体重(kg)",
                "BMI",
                "血型",
                "过敏史",
                "既往病史",
                "当前用药",
                "紧急联系人姓名",
                "紧急联系人关系",
                "紧急联系人电话",
                "记录时间",
                "记录人姓名",
                "记录人职务",
                "所属机构",
                "备注",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                # 处理性别显示
                gender_str = survey.get("gender", "")
                if gender_str == "male":
                    gender_str = "男性"
                elif gender_str == "female":
                    gender_str = "女性"
                elif gender_str == "other":
                    gender_str = "其他"

                # 处理婚姻状况
                marital_str = survey.get("maritalStatus", "")
                marital_map = {
                    "single": "未婚",
                    "married": "已婚",
                    "divorced": "离异",
                    "widowed": "丧偶",
                    "other": "其他",
                }
                marital_str = marital_map.get(marital_str, marital_str)

                # 处理教育程度
                education_str = survey.get("education", "")
                education_map = {
                    "illiterate": "文盲",
                    "primary": "小学",
                    "middle": "初中",
                    "high": "高中/中专",
                    "college": "大专",
                    "university": "本科",
                    "graduate": "研究生及以上",
                }
                education_str = education_map.get(education_str, education_str)

                # 处理是否退休
                retired_str = survey.get("retired", "")
                if retired_str == "yes":
                    retired_str = "是"
                elif retired_str == "no":
                    retired_str = "否"

                # 获取BMI
                bmi_value = ""
                bmi_data = survey.get("bmi")
                if bmi_data and isinstance(bmi_data, dict):
                    bmi_value = bmi_data.get("value", "")

                csv_row = [
                    str(i),
                    survey.get("patientName") or "",
                    survey.get("idCard") or "",
                    str(survey.get("age") or ""),
                    gender_str,
                    survey.get("birthDate") or "",
                    survey.get("phone") or "",
                    survey.get("email") or "",
                    (survey.get("address") or "").replace(",", "；").replace("\n", " ") if survey.get("address") else "",
                    marital_str,
                    education_str,
                    survey.get("occupation") or "",
                    retired_str,
                    str(survey.get("height") or ""),
                    str(survey.get("weight") or ""),
                    bmi_value,
                    survey.get("bloodType") or "",
                    (survey.get("allergies") or "").replace(",", "；").replace("\n", " ") if survey.get("allergies") else "",
                    (survey.get("medicalHistory") or "").replace(",", "；").replace("\n", " ") if survey.get("medicalHistory") else "",
                    (survey.get("currentMedications") or "").replace(",", "；").replace("\n", " ") if survey.get("currentMedications") else "",
                    survey.get("emergencyContactName") or "",
                    survey.get("emergencyContactRelation") or "",
                    survey.get("emergencyContactPhone") or "",
                    survey.get("recordTime") or "",
                    survey.get("recorderName") or "",
                    survey.get("recorderPosition") or "",
                    survey.get("recorderInstitution") or "",
                    (survey.get("remarks") or "").replace(",", "；").replace("\n", " ") if survey.get("remarks") else "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"个人信息登记_问卷调查_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "个人信息" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"个人信息登记数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"个人信息登记导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.get("/api/get-survey-ids")
async def get_survey_ids():
    """获取所有可用的编号列表"""
    try:
        survey_ids = []
        if os.path.exists(DATA_DIR):
            # 获取所有子目录作为编号
            for item in os.listdir(DATA_DIR):
                item_path = os.path.join(DATA_DIR, item)
                if os.path.isdir(item_path):
                    # 检查目录中是否有JSON文件
                    json_files = [
                        f for f in os.listdir(item_path) if f.endswith(".json")
                    ]
                    if json_files:
                        survey_ids.append(item)
        return {"success": True, "surveyIds": sorted(survey_ids)}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取编号列表失败: {str(e)}")


@app.post("/api/save-personality-survey")
async def save_personality_survey(survey_data: PersonalitySurveyData):
    """保存性格特征评估数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"性格特征评估结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "性格特征评估数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-personality-survey")
async def export_personality_survey(request: PersonalityExportRequest):
    """导出性格特征评估数据"""
    try:
        # 验证密码
        if request.password != get_password("personality"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有性格特征评估 JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.endswith(".json") and "性格特征" in f
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有性格特征评估数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"性格特征评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(temp_dir, f"性格特征评估_汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件
            csv_headers = [
                "序号",
                "问答编号",
                "姓名",
                "编号",
                "年龄",
                "性别",
                "联系电话",
                "记录时间",
                "记录人姓名",
                "记录人职务",
                "所属机构",
                "记录人联系方式",
                "备注",
                # 性格特征问题（第一部分）
                "PT01_外向的，热情的",
                "PT02_爱挑剔，好争论",
                "PT03_可靠的，自律的",
                "PT04_焦虑，易心烦的",
                "PT05_容易接纳新事物，能容忍复杂事物的",
                "PT06_保守的，安静的",
                "PT07_有同情心，热心的",
                "PT08_条理不清，粗心的",
                "PT09_平静，情绪稳定的",
                "PT10_传统，枯燥的",
                # 精神状态问题（第二部分）
                "MS01_很难让自己放松安静下来",
                "MS02_感到口干舌燥",
                "MS03_好像不再有快乐的感觉",
                "MS04_感到呼吸困难",
                "MS05_很难主动开始学习或工作",
                "MS06_对事情过于敏感，或反应过度",
                "MS07_感到颤抖",
                "MS08_觉得自己消耗很多精力",
                "MS09_担心一些场合自己会恐慌或出丑",
                "MS10_觉得没有什么可期待盼望的事情",
                "MS11_感到忐忑不安",
                "MS12_感到很难放松自己",
                "MS13_感到情绪低落，消沉沮丧",
                "MS14_无法容忍任何阻碍我继续工作的事情",
                "MS15_感到恐慌，精神或身体快要崩溃了",
                "MS16_对什么事情都没有热情，提不起兴趣",
                "MS17_觉得自己没有价值",
                "MS18_觉得自己很敏感，容易被触怒",
                "MS19_没做什么体力活动时，也感到心律不正常",
                "MS20_会无缘无故地感到害怕",
                "MS21_觉得生命毫无意义",
                # 评估结果
                "性格特征总得分",
                "性格特征平均得分",
                "精神状态总得分",
                "精神状态平均得分",
                "焦虑总得分",
                "焦虑平均得分",
                "焦虑程度",
                "抑郁总得分",
                "抑郁平均得分",
                "抑郁程度",
                "完成度",
                "创建时间",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                # 处理性别
                gender_str = survey.get("gender", "")
                if gender_str == "male":
                    gender_str = "男性"
                elif gender_str == "female":
                    gender_str = "女性"

                # 获取评估结果
                personality_scores = survey.get("personalityScores", {})
                mental_state_scores = survey.get("mentalStateScores", {})
                anxiety_score = mental_state_scores.get("anxietyScore", {}) if mental_state_scores else {}
                depression_score = mental_state_scores.get("depressionScore", {}) if mental_state_scores else {}
                completeness = survey.get("completeness", {})
                
                # 安全处理可能为None的字段
                remarks_str = survey.get("remarks") or ""
                remarks_str = remarks_str.replace(",", "；").replace("\n", " ") if remarks_str else ""
                
                csv_row = [
                    str(i),
                    survey.get("surveyId") or "",
                    survey.get("patientName") or "",
                    survey.get("patientId") or "",
                    str(survey.get("age") or ""),
                    gender_str,
                    survey.get("phone") or "",
                    survey.get("recordTime") or "",
                    survey.get("recorderName") or "",
                    survey.get("recorderPosition") or "",
                    survey.get("recorderInstitution") or "",
                    survey.get("recorderContact") or "",
                    remarks_str,
                    # 性格特征问题
                    str(survey.get("PT01") or ""),
                    str(survey.get("PT02") or ""),
                    str(survey.get("PT03") or ""),
                    str(survey.get("PT04") or ""),
                    str(survey.get("PT05") or ""),
                    str(survey.get("PT06") or ""),
                    str(survey.get("PT07") or ""),
                    str(survey.get("PT08") or ""),
                    str(survey.get("PT09") or ""),
                    str(survey.get("PT10") or ""),
                    # 精神状态问题
                    str(survey.get("MS01") or ""),
                    str(survey.get("MS02") or ""),
                    str(survey.get("MS03") or ""),
                    str(survey.get("MS04") or ""),
                    str(survey.get("MS05") or ""),
                    str(survey.get("MS06") or ""),
                    str(survey.get("MS07") or ""),
                    str(survey.get("MS08") or ""),
                    str(survey.get("MS09") or ""),
                    str(survey.get("MS10") or ""),
                    str(survey.get("MS11") or ""),
                    str(survey.get("MS12") or ""),
                    str(survey.get("MS13") or ""),
                    str(survey.get("MS14") or ""),
                    str(survey.get("MS15") or ""),
                    str(survey.get("MS16") or ""),
                    str(survey.get("MS17") or ""),
                    str(survey.get("MS18") or ""),
                    str(survey.get("MS19") or ""),
                    str(survey.get("MS20") or ""),
                    str(survey.get("MS21") or ""),
                    # 评估结果
                    str(personality_scores.get("totalScore") or ""),
                    str(personality_scores.get("averageScore") or ""),
                    str(mental_state_scores.get("totalScore") or ""),
                    str(mental_state_scores.get("averageScore") or ""),
                    str(anxiety_score.get("total") or ""),
                    str(anxiety_score.get("average") or ""),
                    anxiety_score.get("level", {}).get("level", "") if isinstance(anxiety_score.get("level"), dict) else "",
                    str(depression_score.get("total") or ""),
                    str(depression_score.get("average") or ""),
                    depression_score.get("level", {}).get("level", "") if isinstance(depression_score.get("level"), dict) else "",
                    completeness.get("total", {}).get("percentage", "") if isinstance(completeness.get("total"), dict) else "",
                    survey.get("createdAt") or "",
                ]
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"性格特征评估_问卷调查_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "性格特征" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"性格特征评估数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"性格特征评估导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/save-outdoor-activity-survey")
async def save_outdoor_activity_survey(survey_data: OutdoorActivitySurveyData):
    """保存户外活动记录数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"户外活动记录结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "户外活动记录数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-outdoor-activity-survey")
async def export_outdoor_activity_survey(request: OutdoorActivityExportRequest):
    """导出户外活动记录数据"""
    try:
        # 验证密码（⚠️ 必须使用 get_password() 函数，参数为问卷类型的小写）
        if request.password != get_password("outdooractivity"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有户外活动记录 JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.endswith(".json") and "户外活动" in f
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有户外活动记录数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"户外活动记录数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总记录人数：{len(surveys)}人\n"
            summary_file = os.path.join(temp_dir, f"户外活动记录_汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件（问卷调查）- 根据JSON中的activities数组生成
            category_labels = {
                1: '买菜购物',
                2: '运动锻炼',
                3: '棋牌麻将',
                4: '接送孙辈',
                5: '唱歌跳舞',
                6: '休闲步行',
                7: '跑腿',
                8: '集体活动'
            }

            # CSV表头：个人信息 + 活动记录信息
            csv_headers = [
                "序号",
                "问答编号",
                "姓名",
                "编号",
                "记录日期",
                "居住地址",
                "年龄",
                "性别",
                "联系电话",
                "记录时间",
                "记录人姓名",
                "记录人职务",
                "记录人机构",
                "记录人联系方式",
                "备注",
                # 活动记录信息
                "活动序号",
                "户外行为编号",
                "活动分类",
                "开始时间",
                "步行时长(分钟)",
                "活动场所",
                "使用物品",
                "周末",
                "路线",
                "创建时间",
            ]
            csv_content = ",".join(csv_headers) + "\n"

            row_index = 1  # CSV行序号
            for survey in surveys:
                # 处理性别
                gender_str = survey.get("gender", "")
                if gender_str == "male":
                    gender_str = "男性"
                elif gender_str == "female":
                    gender_str = "女性"

                # 安全处理可能为None的字段
                remarks_str = survey.get("remarks") or ""
                remarks_str = remarks_str.replace(",", "；").replace("\n", " ") if remarks_str else ""

                # 个人信息（每条活动记录都会重复）
                patient_info = [
                    str(row_index),
                    survey.get("surveyId") or "",
                    survey.get("patientName") or "",
                    survey.get("patientId") or "",
                    survey.get("recordDate") or "",
                    survey.get("residenceAddress") or "",
                    str(survey.get("age") or ""),
                    gender_str,
                    survey.get("phone") or "",
                    survey.get("recordTime") or "",
                    survey.get("recorderName") or "",
                    survey.get("recorderPosition") or "",
                    survey.get("recorderInstitution") or "",
                    survey.get("recorderContact") or "",
                    remarks_str,
                ]

                # 获取活动记录列表
                activities = survey.get("activities", [])
                
                if activities and len(activities) > 0:
                    # 如果有活动记录，为每条活动生成一行
                    for activity in activities:
                        # 处理活动分类
                        category = activity.get("category")
                        category_str = ""
                        if category:
                            category_str = f"{category}. {category_labels.get(int(category), '未知')}"
                        
                        # 处理周末标识
                        is_weekend = activity.get("isWeekend", False)
                        weekend_str = "是" if is_weekend else "否"
                        
                        # 处理开始时间（格式化显示）
                        start_time = activity.get("startTime", "")
                        if start_time:
                            # 尝试格式化ISO格式时间字符串
                            try:
                                # datetime.fromisoformat可以处理大部分ISO格式
                                # 但对于Z后缀（UTC），需要替换
                                time_str = start_time.replace("Z", "+00:00") if start_time.endswith("Z") else start_time
                                dt_obj = datetime.fromisoformat(time_str)
                                start_time = dt_obj.strftime("%Y-%m-%d %H:%M")
                            except (ValueError, AttributeError):
                                # 如果解析失败，保持原样
                                pass
                        
                        # 处理路线（处理换行和逗号）
                        route = activity.get("route", "") or ""
                        route = route.replace(",", "；").replace("\n", " ") if route else ""
                        
                        # 活动记录信息
                        activity_info = [
                            str(activity.get("index", "")),  # 活动序号
                            activity.get("activityCode", "") or "",  # 户外行为编号
                            category_str,  # 活动分类
                            start_time,  # 开始时间
                            str(activity.get("duration", "")) if activity.get("duration") else "",  # 步行时长
                            activity.get("venue", "") or "",  # 活动场所
                            activity.get("itemsUsed", "") or "",  # 使用物品
                            weekend_str,  # 周末
                            route,  # 路线
                            survey.get("createdAt", ""),  # 创建时间
                        ]
                        
                        # 合并个人信息和活动信息
                        csv_row = patient_info + activity_info
                        csv_content += ",".join(csv_row) + "\n"
                        row_index += 1
                else:
                    # 如果没有活动记录，至少生成一行基本信息（活动信息为空）
                    activity_info = [
                        "",  # 活动序号
                        "",  # 户外行为编号
                        "",  # 活动分类
                        "",  # 开始时间
                        "",  # 步行时长
                        "",  # 活动场所
                        "",  # 使用物品
                        "",  # 周末
                        "",  # 路线
                        survey.get("createdAt") or "",  # 创建时间
                    ]
                    csv_row = patient_info + activity_info
                    csv_content += ",".join(csv_row) + "\n"
                    row_index += 1

            csv_file = os.path.join(temp_dir, f"户外活动记录_问卷调查_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "户外活动" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"户外活动记录数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"户外活动记录导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/save-leisure-activity-survey")
async def save_leisure_activity_survey(survey_data: LeisureActivitySurveyData):
    """保存空闲活动频率量表数据"""
    try:
        # 确保目录存在
        survey_dir = os.path.join(DATA_DIR, survey_data.surveyId)
        os.makedirs(survey_dir, exist_ok=True)

        # 生成文件名
        timestamp = datetime.now().strftime("%Y-%m-%dT%H-%M-%S")
        patient_name = survey_data.patientName or "未填写"
        filename = f"空闲活动频率评估结果_{survey_data.surveyId}_{patient_name}_{timestamp}.json"
        filepath = os.path.join(survey_dir, filename)

        # 保存JSON数据
        with open(filepath, "w", encoding="utf-8") as f:
            json.dump(survey_data.model_dump(), f, ensure_ascii=False, indent=2)

        return {"message": "空闲活动频率量表数据保存成功", "filename": filename}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"保存失败: {str(e)}")


@app.post("/api/export-leisure-activity-survey")
async def export_leisure_activity_survey(request: LeisureActivityExportRequest):
    """导出空闲活动频率量表数据"""
    try:
        # 验证密码（⚠️ 必须使用 get_password() 函数，参数为问卷类型的小写）
        if request.password != get_password("leisureactivity"):
            raise HTTPException(status_code=401, detail="密码错误")

        survey_id = request.surveyId

        # 检查数据目录是否存在
        group_dir = os.path.join(DATA_DIR, survey_id)
        if not os.path.exists(group_dir):
            raise HTTPException(
                status_code=404, detail=f"未找到问卷组 {survey_id} 的数据"
            )

        # 读取所有空闲活动频率评估 JSON文件
        json_files = [
            f
            for f in os.listdir(group_dir)
            if f.endswith(".json") and "空闲活动" in f
        ]
        if not json_files:
            raise HTTPException(
                status_code=404, detail=f"问卷组 {survey_id} 中没有空闲活动频率评估数据"
            )

        surveys = []
        for json_file in json_files:
            filepath = os.path.join(group_dir, json_file)
            with open(filepath, "r", encoding="utf-8") as f:
                survey_data = json.load(f)
                surveys.append(survey_data)

        # 创建临时目录用于生成导出文件
        with tempfile.TemporaryDirectory() as temp_dir:
            # 生成汇总报告
            summary_content = f"空闲活动频率评估数据汇总报告\n问答编号：{survey_id}\n生成时间：{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n总评估人数：{len(surveys)}人\n"
            summary_file = os.path.join(temp_dir, f"空闲活动频率评估_汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件（问卷调查）
            activity_labels = {
                'Q01': '做家务',
                'Q02': '带孩子社区玩',
                'Q03': '买菜购物',
                'Q04': '广场舞/健身操',
                'Q05': '功夫（太极拳/武术等）',
                'Q06': '球类运动',
                'Q07': '健身器材锻炼',
                'Q08': '散步',
                'Q09': '读书/看报纸/杂志/看电视',
                'Q10': '上网/玩手机',
                'Q11': '个人音乐/书法/绘画',
                'Q12': '种花/养宠物',
                'Q13': '棋牌/麻将',
                'Q14': '参加团体活动/亲友聊天'
            }
            
            frequency_labels = {
                1: '从不参加',
                2: '一年数次',
                3: '一月数次',
                4: '一周数次',
                5: '几乎每天'
            }

            csv_headers = [
                "序号",
                "问答编号",
                "姓名",
                "编号",
                "记录日期",
                "年龄",
                "性别",
                "联系电话",
                "测量地点",
                "测量人员",
                "记录时间",
                "记录人姓名",
                "记录人职务",
                "记录人机构",
                "记录人联系方式",
                "备注",
            ]
            # 添加14个活动频率列
            for q_id in ['Q01', 'Q02', 'Q03', 'Q04', 'Q05', 'Q06', 'Q07', 'Q08', 'Q09', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14']:
                csv_headers.append(activity_labels[q_id])
            csv_headers.extend([
                "健身器材选择",
                "总得分",
                "平均分",
                "已回答项数",
                "活动参与度",
                "从不参加项数",
                "一年数次项数",
                "一月数次项数",
                "一周数次项数",
                "几乎每天项数",
                "创建时间"
            ])
            
            csv_content = ",".join(csv_headers) + "\n"

            for i, survey in enumerate(surveys, 1):
                # 处理性别
                gender_str = survey.get("gender", "")
                if gender_str == "male":
                    gender_str = "男性"
                elif gender_str == "female":
                    gender_str = "女性"

                # 安全处理可能为None的字段
                remarks_str = survey.get("remarks") or ""
                remarks_str = remarks_str.replace(",", "；").replace("\n", " ") if remarks_str else ""
                
                # 处理健身器材选择
                fitness_equipment = survey.get("fitnessEquipment", [])
                fitness_str = ",".join([str(x) for x in fitness_equipment]) if fitness_equipment else ""
                
                # 处理活动参与度
                participation_level = survey.get("participationLevel", {})
                participation_str = participation_level.get("level", "") if participation_level else ""

                csv_row = [
                    str(i),
                    survey.get("surveyId") or "",
                    survey.get("patientName") or "",
                    survey.get("patientId") or "",
                    survey.get("recordDate") or "",
                    str(survey.get("age") or "") if survey.get("age") else "",
                    gender_str,
                    survey.get("phone") or "",
                    survey.get("measurementLocation") or "",
                    survey.get("measurementPerson") or "",
                    survey.get("recordTime") or "",
                    survey.get("recorderName") or "",
                    survey.get("recorderPosition") or "",
                    survey.get("recorderInstitution") or "",
                    survey.get("recorderContact") or "",
                    remarks_str,
                ]
                # 添加14个活动频率
                for q_id in ['Q01', 'Q02', 'Q03', 'Q04', 'Q05', 'Q06', 'Q07', 'Q08', 'Q09', 'Q10', 'Q11', 'Q12', 'Q13', 'Q14']:
                    q_value = survey.get(q_id)
                    if q_value:
                        csv_row.append(frequency_labels.get(int(q_value), str(q_value)))
                    else:
                        csv_row.append("")
                
                # 添加统计信息
                csv_row.extend([
                    fitness_str,
                    str(survey.get("totalScore", "")) if survey.get("totalScore") else "",
                    str(survey.get("averageScore", "")) if survey.get("averageScore") else "",
                    str(survey.get("answeredCount", "")) if survey.get("answeredCount") else "",
                    participation_str,
                    str(survey.get("statistics", {}).get("neverParticipate", "")) if survey.get("statistics", {}).get("neverParticipate") is not None else "",
                    str(survey.get("statistics", {}).get("yearlyParticipate", "")) if survey.get("statistics", {}).get("yearlyParticipate") is not None else "",
                    str(survey.get("statistics", {}).get("monthlyParticipate", "")) if survey.get("statistics", {}).get("monthlyParticipate") is not None else "",
                    str(survey.get("statistics", {}).get("weeklyParticipate", "")) if survey.get("statistics", {}).get("weeklyParticipate") is not None else "",
                    str(survey.get("statistics", {}).get("dailyParticipate", "")) if survey.get("statistics", {}).get("dailyParticipate") is not None else "",
                    survey.get("createdAt") or "",
                ])
                
                csv_content += ",".join(csv_row) + "\n"

            csv_file = os.path.join(temp_dir, f"空闲活动频率评估_问卷调查_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8-sig") as f:
                f.write(csv_content)

            # 复制JSON数据文件
            json_data_dir = os.path.join(temp_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            # 复制个人评估报告文件（如果存在）
            report_dir = os.path.join(REPORT_DIR, survey_id)
            individual_dir = None
            if os.path.exists(report_dir):
                individual_dir = os.path.join(temp_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for filename in os.listdir(report_dir):
                    if "空闲活动" in filename and filename.endswith(".txt"):
                        src = os.path.join(report_dir, filename)
                        dst = os.path.join(individual_dir, filename)
                        shutil.copy2(src, dst)

            # 创建ZIP文件
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            zip_filename = f"空闲活动频率评估数据_{survey_id}_{timestamp}.zip"
            zip_filepath = os.path.join(temp_dir, zip_filename)

            with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
                # 1. 添加JSON数据文件
                if os.path.exists(json_data_dir):
                    for root, dirs, files in os.walk(json_data_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 2. 添加个人评估报告
                if individual_dir and os.path.exists(individual_dir):
                    for root, dirs, files in os.walk(individual_dir):
                        for file in files:
                            file_path = os.path.join(root, file)
                            arc_name = os.path.relpath(file_path, temp_dir)
                            zipf.write(file_path, arc_name)
                # 3. 添加汇总报告
                zipf.write(summary_file, os.path.basename(summary_file))
                # 4. 添加问卷调查（CSV）
                zipf.write(csv_file, os.path.basename(csv_file))

            # 将ZIP文件移动到temp目录供下载（避免临时目录被删除）
            final_zip_path = os.path.join("temp", zip_filename)
            os.makedirs("temp", exist_ok=True)
            shutil.move(zip_filepath, final_zip_path)

            print(f"空闲活动频率评估导出文件已生成: {final_zip_path}")
            return FileResponse(
                final_zip_path, media_type="application/zip", filename=zip_filename
            )

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"导出失败: {str(e)}")


@app.post("/api/batch-export")
async def batch_export(request: BatchExportRequest):
    """批量导出多个编号的问卷数据"""
    try:
        # 验证密码
        if request.password != get_password("batch"):
            raise HTTPException(status_code=401, detail="密码错误")

        if not request.surveyIds or len(request.surveyIds) == 0:
            raise HTTPException(status_code=400, detail="请至少选择一个编号")

        # 创建临时目录
        temp_dir = tempfile.mkdtemp()
        exported_count = 0  # 记录成功导出的编号数量

        # 为每个编号导出数据
        for survey_id in request.surveyIds:
            group_dir = os.path.join(DATA_DIR, survey_id)
            if not os.path.exists(group_dir):
                continue

            # 读取所有JSON文件
            json_files = [f for f in os.listdir(group_dir) if f.endswith(".json")]
            if not json_files:
                continue

            surveys = []
            for json_file in json_files:
                filepath = os.path.join(group_dir, json_file)
                with open(filepath, "r", encoding="utf-8") as f:
                    survey_data = json.load(f)
                    surveys.append(survey_data)

            if not surveys:
                continue

            # 为每个编号创建子目录
            survey_dir = os.path.join(temp_dir, survey_id)
            os.makedirs(survey_dir, exist_ok=True)

            # 生成汇总报告
            summary_content = ReportGenerator.generate_summary_report(
                surveys, survey_id
            )
            summary_file = os.path.join(survey_dir, f"汇总报告_{survey_id}.txt")
            with open(summary_file, "w", encoding="utf-8") as f:
                f.write(summary_content)

            # 生成CSV文件
            csv_content = ReportGenerator.generate_csv_report(surveys)
            csv_file = os.path.join(survey_dir, f"问卷数据_{survey_id}.csv")
            with open(csv_file, "w", encoding="utf-8") as f:
                f.write(csv_content)

            # 复制个人报告文件
            report_group_dir = os.path.join(REPORT_DIR, survey_id)
            if os.path.exists(report_group_dir):
                individual_dir = os.path.join(survey_dir, "个人评估报告")
                os.makedirs(individual_dir, exist_ok=True)
                for report_file in os.listdir(report_group_dir):
                    if report_file.endswith(".txt"):
                        src = os.path.join(report_group_dir, report_file)
                        dst = os.path.join(individual_dir, report_file)
                        shutil.copy2(src, dst)

            # 复制JSON数据文件
            json_data_dir = os.path.join(survey_dir, "JSON数据")
            os.makedirs(json_data_dir, exist_ok=True)
            for json_file in json_files:
                src = os.path.join(group_dir, json_file)
                dst = os.path.join(json_data_dir, json_file)
                shutil.copy2(src, dst)

            exported_count += 1

        # 检查是否有成功导出的数据
        if exported_count == 0:
            raise HTTPException(status_code=404, detail="所选编号下没有数据")

        # 创建总压缩包
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        zip_filename = f"批量导出数据_{timestamp}.zip"
        zip_filepath = os.path.join(temp_dir, zip_filename)

        with zipfile.ZipFile(zip_filepath, "w", zipfile.ZIP_DEFLATED) as zipf:
            # 遍历所有编号的目录
            for root, dirs, files in os.walk(temp_dir):
                # 跳过根目录本身
                if root == temp_dir:
                    continue
                for file in files:
                    if file == zip_filename:
                        continue
                    file_path = os.path.join(root, file)
                    # 计算在压缩包中的相对路径
                    arc_name = os.path.relpath(file_path, temp_dir)
                    zipf.write(file_path, arc_name)

        # 检查压缩包是否为空
        if not os.path.exists(zip_filepath) or os.path.getsize(zip_filepath) == 0:
            raise HTTPException(status_code=404, detail="所选编号下没有数据")

        # 将ZIP文件移动到temp目录供下载
        final_zip_path = os.path.join("temp", zip_filename)
        os.makedirs("temp", exist_ok=True)
        shutil.move(zip_filepath, final_zip_path)

        print(f"批量导出文件已生成: {final_zip_path}")
        return FileResponse(
            final_zip_path, media_type="application/zip", filename=zip_filename
        )

    except HTTPException:
        raise
    except Exception as e:
        print(f"批量导出数据失败: {e}")
        raise HTTPException(status_code=500, detail="批量导出数据失败")


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=13000)
